package com.db.ionio.nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;

/**
 * @author Alexander Kotov (kotov.alex.22@gmail.com)
 */
public class FileNIOClient {
    private final String hostName;
    private final int port;
    private final String fileName;

    public FileNIOClient(String hostName, int port, String fileName) {
        this.hostName = hostName;
        this.port = port;
        this.fileName = fileName;
    }

    public void start() {
        long start = System.nanoTime();
        run();
        long time = System.nanoTime() - start;
        System.out.println(time);
    }

    private void run() {
        try (
                SocketChannel channel = SocketChannel.open();
                FileChannel fileChannel = new FileInputStream(new File(fileName)).getChannel();
        ) {
            channel.connect(new InetSocketAddress(hostName, port));

            long fileSize = new File(fileName).length();
            System.out.format("file size is %d%n", fileSize);

            ByteBuffer byteBuffer = ByteBuffer.allocate(8);
            byteBuffer.putLong(0, fileSize);
            System.out.println(channel.write(byteBuffer));
            byteBuffer.clear();

            int currentBytesTransferred = 0;
            System.out.println("Start copy...");

            while (currentBytesTransferred != fileChannel.size()) {
                currentBytesTransferred += fileChannel.transferTo(currentBytesTransferred, fileChannel.size(), channel);
            }

            System.out.println("Copy done. Wait for response...");

            byte[] bytes = new byte[1024];
            channel.read(ByteBuffer.wrap(bytes));
            System.out.println(new String(bytes));

        } catch (UnknownHostException unknownHostException) {
            unknownHostException.printStackTrace();
            System.err.println("Connection to unknown host failed");
        } catch (IOException ioException) {
            ioException.printStackTrace();
            System.err.println(ioException.getMessage());
        } catch (NullPointerException nullPointerException) {
            nullPointerException.printStackTrace();
            System.err.println(nullPointerException.getMessage());
        }
    }
}